import './BeiHuanMap.scss'
import { Button } from 'antd'
import { useState, useRef } from 'react'
import { useRequest, useEventEmitter, useMount } from 'ahooks'

import { Http } from '../../../../Common/Api'
import { Initialization, InitializationData } from '../../../../Common/Mars3d/Initialization'

import { project } from '../../../../Common/Data'
import { getRandomNumber } from '../../../../Common/Configure/Common'

import { commonUrl } from '../../../../Common/Configure/CommonParameter'
import { FrontModalBox } from '../Modal'

const { mars3d, Cesium } = window

const { imageUrl } = project[window.location.hostname]

// 地图数据
const additional = {
    scene: {
        sceneMode: 3,
        orderIndependentTranslucency: false,
        contextOptions: { webgl: { alpha: true } },
        showSun: false,
        showMoon: false,
        showSkyBox: false,
        showSkyAtmosphere: true,
        requestRenderMode: true,
        scene3DOnly: true,
        shadows: false,
        removeDblClick: true,
        fog: true,
        fxaa: true,
    },
}
// 泛光属性
const bloomEffect = {
    enabled: true,
    contrast: 128,
    brightness: -0.3,
    delta: 1,
    sigma: 3.78,
    stepSize: 5,
}

// 白膜数据
const Leukorrhea = () => {
    return new Cesium.CustomShader({
        uniforms: {
            u_envTexture: {
                value: new Cesium.TextureUniform({
                    url: '/img/textures/buildings-kj.jpg',
                }),
                type: Cesium.UniformType.SAMPLER_2D,
            },
            u_build1: {
                type: Cesium.UniformType.SAMPLER_2D,
                value: new Cesium.TextureUniform({
                    url: '/img/textures/buildings-colors.png',
                }),
            },
            u_lerp: {
                type: Cesium.UniformType.FLOAT,
                value: -100,
            },
            u_lightPosition: {
                type: Cesium.UniformType.VEC3,
                value: Cesium.Cartesian3.fromDegrees(126.637858, 45.756151, 164.8),
            },
            u_lightColor: {
                type: Cesium.UniformType.VEC3,
                value: Cesium.Color.fromCssColorString('#FF4500'),
            },
            u_lightPosition2: {
                type: Cesium.UniformType.VEC3,
                value: Cesium.Cartesian3.fromDegrees(126.674947, 45.745375, 181.6),
            },
            u_lightColor2: {
                type: Cesium.UniformType.VEC3,
                value: Cesium.Color.fromCssColorString('#6900ff'),
            },
            u_lightRadius: {
                type: Cesium.UniformType.FLOAT,
                value: 2000,
            },
            u_play: {
                type: Cesium.UniformType.BOOL,
                value: true,
            },
            u_lerp2: {
                type: Cesium.UniformType.FLOAT,
                value: 0,
            },
            u_color: {
                type: Cesium.UniformType.VEC4,
                value: Cesium.Color.fromCssColorString('#62809b'),
            },
        },
        mode: Cesium.CustomShaderMode.REPLACE_MATERIAL,
        lightingModel: Cesium.LightingModel.UNLIT,
        fragmentShaderText: `
        #define sat( a ) clamp( a, 0.0, 1.0 )
        float noise_fun(vec2 co) {
            return fract(sin(dot(co.xy ,vec2(12.45678, 93.970204))) * 4321.12345) * 20.;
        }
        float getDistanceDecay( float lightDistance, float distance,float decay) {
            if ( distance > 0.0 && decay > 0.0 ) {
                return pow( sat( - lightDistance / distance + 1.0 ), decay );
            }
            return 1.0;
        }
        vec3 addPointLight(vec3 lightPosition, vec3 lightColor, vec3 positionWC , vec3 normal){
            float distance = u_lightRadius;
            float decay = 1.0;
            float lightDistance = length( lightPosition - positionWC );
            lightColor *= getDistanceDecay( lightDistance, distance, decay );
            return lightColor;
        }
        void fragmentMain(FragmentInput fsInput,inout czm_modelMaterial material) {
            vec3 positionMC = fsInput.attributes.positionMC;
            vec3 positionEC = fsInput.attributes.positionEC;
            vec3 normalEC = fsInput.attributes.normalEC;
            vec3 posToCamera = normalize(-positionEC);
            vec2 uv = fsInput.attributes.texCoord_0;
            float diffuseCoefficient = max(0.0, dot(normalEC, vec3(0.2)) * 1.0);
            vec4 glColor1 = vec4(0.);
            vec4 glColor2 = vec4(0.);
            {
                float heightInterval = 50.0;
                float lineWidth = 10.0;
                float modResult = mod(positionMC.z, heightInterval);
                vec3 finalColor = vec3(0.3);
                vec4 textureColor3 = texture(u_build1,vec2(fract(uv.s),float(uv.t * 5.0) - (czm_frameNumber/60.)));
                if (modResult < lineWidth / 2.0) {
                    finalColor = textureColor3.rgb * 2.5;
                }
                glColor1.rgb = mix(u_color.rgb * 1.5, finalColor,clamp(positionMC.z / 20., 0.0, 1.0));
                glColor1.rgb *= min(diffuseCoefficient + 0.2, 1.0);
                glColor1.a = 1.0;
            }
            {
                vec3 coord = normalize(vec3(czm_inverseViewRotation * reflect(posToCamera, normalEC)));
                vec4 darkRefColor = texture(u_envTexture, vec2(coord.x, (coord.z - coord.y) / 2.0));
                glColor2.rgb = mix(mix(vec3(.2), vec3(.1,.2,.6),clamp(positionMC.z / 400., 0.0, 1.0)) , darkRefColor.rgb ,0.2);
                glColor2.rgb *= min(diffuseCoefficient + 0.1, 1.0);
  
                // 基础点光源高亮指定范围
                glColor2.rgb += addPointLight(
                    u_lightPosition ,
                    u_lightColor,
                    (czm_model * vec4(positionMC,1.0)).xyz ,
                    normalEC);
                glColor2.rgb += addPointLight(
                    u_lightPosition2 ,
                    u_lightColor2,
                    (czm_model * vec4(positionMC,1.0)).xyz ,
                    normalEC);
  
                // cesiumlab 光圈特效
                float _baseHeight = 0.0;
                float _heightRange = 20.0;
                float _glowRange = 300.0;
                float czm_height = positionMC.z - _baseHeight;
                float czm_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
                float czm_a12 = czm_height / _heightRange + sin(czm_a11) * 0.1;
                float times = czm_frameNumber / 60.0;
                glColor2.rgb *= vec3(czm_a12);// 渐变
                float time = fract(czm_frameNumber / 360.0);
                time = abs(time - 0.5) * 2.0;
                float czm_h = clamp(czm_height / _glowRange, 0.0, 1.0);
                float czm_diff = step(0.005, abs(czm_h - time));
                glColor2.rgb += glColor2.rgb * (1.0 - czm_diff);
                glColor2.a = 1.0;
            }
  
            float noise = noise_fun(vec2(positionMC.x, positionMC.y));
            bool condition1 = positionMC.z > (u_lerp + noise);
            bool condition2 = u_play && u_lerp < 0. && u_lerp2 < positionEC.x && positionEC.x < u_lerp2 + 350.;
            bool condition3 = u_play && u_lerp > 800. && u_lerp2 < positionEC.x && positionEC.x < u_lerp2 + 350.;
  
            material.diffuse = mix(glColor2.rgb, glColor1.rgb, float(condition1 || condition2 || condition3));
            material.alpha = mix(glColor2.a, glColor1.a, float(condition1 || condition2 || condition3));
  
        }
             `,
    })
}

// 视角飞行
const CameraView = map => {
    const viewPoints = [
        // { lat: 45.474725, lng: 126.41317, alt: 27451.1, heading: 23.5, pitch: -48, duration: 0, stop: 0 },
        // { "lat": 45.689175, "lng": 126.61082, "alt": 4700.7, "heading": 23.5, "pitch": -48, duration: 4, stop: 0 },
        // { "lat": 45.730688, "lng": 126.649989, "alt": 2469.6, "heading": 23.5, "pitch": -48, duration: 4, stop: 0 },
        { lat: 45.965472, lng: 126.885696, alt: 2690.8, heading: 21.2, pitch: -29.5, duration: 6 },
    ]
    map.setCameraViewList(viewPoints)
}

// 船只数据
const ShipRender = (gra, route) => {
    const shipArr = [
        { uuid: 1, label: '1号船' },
        { uuid: 2, label: '2号船' },
        { uuid: 3, label: '3号船' },
        { uuid: 4, label: '4号船' },
        { uuid: 5, label: '5号船' },
        { uuid: 6, label: '6号船' },
        { uuid: 7, label: '7号船' },
        { uuid: 8, label: '8号船' },
        { uuid: 9, label: '9号船' },
    ]
    // 船只
    shipArr.forEach(({ uuid, label }) => {
        const speed = getRandomNumber(100, 160)
        const positions = route[uuid - 1].position
        const fixedRoute = new mars3d.graphic.FixedRoute({
            name: label,
            speed,
            positions,
            clockLoop: true,
            updateClock: false,
            model: {
                url: '//data.mars3d.cn/gltf/mars/ship/ship05.glb',
                heading: 180,
                mergeOrientation: true,
                minimumPixelSize: 50,
            },
        })
        gra.addGraphic(fixedRoute)
        fixedRoute.start()
    })
}

// 标签数据
const BerthRender = (gra, berth) => {
    const data = {
        A01: 500,
        A02: 240,
        A03: 260,
        B01: 600,
        B02: 280,
        B03: 320,
    }
    berth.forEach(({ position, color, tableName, sortId, ...item }) => {
        position[2] = 300
        const tetrahedronPrimitive = new mars3d.graphic.Tetrahedron({
            position,
            style: { width: 40, height: 50, color, moveHeight: 30, moveDuration: 1 },
        })
        const DIV = new mars3d.graphic.DivGraphic({
            position,
            style: {
                html: ` <div class="BeihuanBox">
                            <div class="Text">
                                <div class='front'>${tableName} : <span> ${
                    sortId === 101 ? data.A01 : data.B01
                }m³ </span> </div>
                                <div class='back'>
                                    <div>A : <span> ${sortId === 101 ? data.A02 : data.B02}m³ </span> </div>
                                    <div>B : <span> ${sortId === 101 ? data.A03 : data.B03}m³ </span> </div>
                                </div>
                            </div>
                        </div>`,
                highlight: {},
            },
        })
        gra.addGraphic(DIV)
        gra.addGraphic(tetrahedronPrimitive)
    })
}

const MonitorRender = (gra, monitor, ClickEvent) => {
    monitor.forEach(({ position, color, tableName, sortId, elementDetailUuid, ...item }) => {
        const DIV = new mars3d.graphic.DivGraphic({
            id: `monitor-${elementDetailUuid}`,
            position,
            style: {
                html: ` <div class="MonitorRender" id='click'>
                            <div class="Text"> 
                                ${tableName} 
                                <img src='${imageUrl}monitor.png'/>
                            </div>
                        </div>`,
                highlight: {},
            },
        })
        gra.addGraphic(DIV)
    })

    gra.on(mars3d.EventType.click, e => {
        const list = ['monitor-2b6f3e1e-a346-4623-adb4-e6871008221c', 'monitor-93749871-9d2e-41f3-b0f0-2999c240dd6b']
        if (list.includes(e.graphic.id)) {
            ClickEvent.emit({ type: 'monitor', data: { url: 'https://stream.ljkjkf.com/vhls/10001/10001_live.m3u8' } })
        }
    })
}

export const BeiHuanBMap = ({ sceneId }) => {
    const MapBox = useRef(null)
    const InitializationEvent = useEventEmitter()
    const center = { lat: 45.96615, lng: 126.906966, alt: 2945.5, heading: 5.2, pitch: -28.7 }

    const [Map, setMap] = useState()
    const [OptionsCall, setOptionsCall] = useState()

    const ClickEvent = useEventEmitter()
    ClickEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'monitor') setOptionsCall({ type: 'Annex', data })
    })

    InitializationEvent.useSubscription(({ map, gra, uuid, clip }) => {
        map.addEffect(new mars3d.effect.BloomEffect(bloomEffect))
        // const model = new mars3d.layer.OsmBuildingsLayer({ marsJzwStyle: true })
        // model.customShader = Leukorrhea()
        // map.addLayer(model)
        map.centerAt(center)
        setMap(map)
        CameraView(map)

        getScenesDetailsUuid({ url: `getScenesDetailsUuid`, path: [uuid] }).then(res => {
            InitializationData(map, gra, res, true, clip)
            const { elements } = res
            const route = elements.find(v => v.elementUuid === 'd8cdc35a-9327-4491-acd8-85165cc7a8dc').elementDetails
            const berth = elements.find(v => v.elementUuid === 'c226bb61-423c-4862-b4a0-dc694efb3f2b').elementDetails
            const monitor = elements.find(v => v.elementUuid === '207c062a-3a71-4ea6-bdf1-63b4d8dfc416').elementDetails
            ShipRender(gra, route)
            BerthRender(gra, berth)
            MonitorRender(gra, monitor, ClickEvent)

            // const tiles3dLayer = new mars3d.layer.TilesetLayer({
            //     name: '哈尔滨',
            //     url: 'https://image.ljkjkf.com/intellisiteSystem_TieKe/Scene/tiles/harbin/tileset.json',
            //     position: [126.637095, 45.751358, 180],
            //     maximumScreenSpaceError: 1,
            //     // projectTo2D: true,
            //     popup: [
            //         { field: 'objectid', name: '编号' },
            //         { field: 'name', name: '名称' },
            //         { field: 'height', name: '楼高', unit: '米' },
            //     ],
            // })
            // map.addLayer(tiles3dLayer)

            // tiles3dLayer.marsJzwStyle = false
            // tiles3dLayer.customShader = Leukorrhea()

            // tiles3dLayer.customShader = undefined
            // tiles3dLayer.marsJzwStyle = {
            //     baseHeight: 200.0, // 物体的基础高度，需要修改成一个合适的建筑基础高度
            //     heightRange: 500.0, // 高亮的范围  (baseHeight ~ baseHeight + heightRange)
            //     glowRange: 300.0 // 光环的移动范围
            // }

            // tiles3dLayer.style = new Cesium.Cesium3DTileStyle({
            //     color: {
            //         conditions: [["true", `rgba(21,194,39,1)`]]
            //     }
            // })
        })
    })

    const { runAsync: getScenesDetailsUuid } = useRequest(Http, { manual: true })
    const { runAsync: getScenes } = useRequest(Http, {
        manual: true,
        onSuccess: res => Initialization(res, MapBox, InitializationEvent, additional),
    })
    useMount(() => {
        getScenes({ url: `getScenesID`, path: [sceneId] })
    })

    return (
        <div className="BeiHuanBMap">
            <div className="Map" ref={MapBox} />
            <div className="options">
                <Button onClick={() => Map.centerAt(center)}>视角复位</Button>
            </div>
            <FrontModalBox OptionsCall={OptionsCall} />
        </div>
    )
}
